package com.darly.book.presenter;


import com.darly.book.BookController;
import com.darly.book.model.bean.BookDetailBean;
import com.darly.book.model.remote.BookApi;
import com.darly.book.presenter.contract.BookShelfContract;
import com.darly.book.ui.base.RxPresenter;
import com.darly.book.utils.Constant;
import com.darly.book.utils.MD5Utils;
import com.darly.book.utils.RxUtils;
import com.darly.book.utils.StringUtils;
import com.darly.chinese.db.book.table.BookChapterBean;
import com.darly.chinese.db.book.table.CollBookBean;
import com.darly.chinese.db.book.table.DownloadTaskBean;
import com.darly.dlcommon.common.dlog.DLog;
import com.darly.dlcommon.db.version.DataBaseController;
import com.darly.dlcommon.retrofit.RxjavaRetrofitRequestUtil;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import okhttp3.MediaType;
import okhttp3.RequestBody;

public class BookShelfPresenter extends RxPresenter<BookShelfContract.View>
        implements BookShelfContract.Presenter {
    private static final String TAG = "BookShelfPresenter";

    @Override
    public void testService() {
        Disposable disposable = RxjavaRetrofitRequestUtil.getInstance().getWithHost(BookApi.class, "http://localhost:8013/")
                .testService()
                .doOnSuccess(new Consumer<String>() {
                    @Override
                    public void accept(String collBooks) throws Exception {
                    }
                })
                .compose(RxUtils::toSimpleSingle)
                .subscribe(
                        beans -> {

                        },
                        (e) -> {

                        }
                );
        addDisposable(disposable);
        JSONObject param = new JSONObject();
        try {
            param.put("username", "123");
            param.put("password", RxjavaRetrofitRequestUtil.md5("123"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), param.toString());
        Disposable d = RxjavaRetrofitRequestUtil.getInstance().postWithHost(BookApi.class, "http://localhost:8013/")
                .testLogin(body)
                .doOnSuccess(new Consumer<String>() {
                    @Override
                    public void accept(String collBooks) throws Exception {
                    }
                })
                .compose(RxUtils::toSimpleSingle)
                .subscribe(
                        beans -> {

                        },
                        (e) -> {

                        }
                );
        addDisposable(d);


    }

    @Override
    public void refreshCollBooks() {
        List<CollBookBean> collBooks = DataBaseController.selectAll(CollBookBean.class);
        mView.finishRefresh(collBooks);
    }

    @Override
    public void createDownloadTask(CollBookBean collBookBean) {
        DownloadTaskBean task = new DownloadTaskBean();
        task.setTaskName(collBookBean.getTitle());
        task.setBookId(collBookBean.get_id());
        task.setBookChapters(collBookBean.getBookChapters());
        task.setLastChapter(collBookBean.getBookChapters().size());

        BookController.getInstance().post(task);
    }


    @Override
    public void loadRecommendBooks(String gender) {
        Disposable disposable = RxjavaRetrofitRequestUtil.getInstance().getWithHost(BookApi.class, Constant.API_BASE_URL)
                .getRecommendBookPackage(gender)
                .map(bean -> bean.getBooks())
                .doOnSuccess(new Consumer<List<CollBookBean>>() {
                    @Override
                    public void accept(List<CollBookBean> collBooks) throws Exception {
                        //更新目录
                        updateCategory(collBooks);
                        //异步存储到数据库中
//                        BookRepository.getInstance()
//                                .saveCollBooksWithAsync(collBooks);
                    }
                })
                .compose(RxUtils::toSimpleSingle)
                .subscribe(
                        beans -> {
                            mView.finishRefresh(beans);
                            mView.complete();
                        },
                        (e) -> {
                            //提示没有网络
                            DLog.e(e);
                            mView.showErrorTip(e.toString());
                            mView.complete();
                        }
                );
        addDisposable(disposable);
    }


    //需要修改
    @Override
    public void updateCollBooks(List<CollBookBean> collBookBeans) {
        if (collBookBeans == null || collBookBeans.isEmpty()) return;
        List<CollBookBean> collBooks = new ArrayList<>(collBookBeans);
        List<Single<BookDetailBean>> observables = new ArrayList<>(collBooks.size());
        Iterator<CollBookBean> it = collBooks.iterator();
        while (it.hasNext()) {
            CollBookBean collBook = it.next();
            //删除本地文件
            if (collBook.isLocal()) {
                it.remove();
            } else {
                observables.add(RxjavaRetrofitRequestUtil.getInstance().getWithHost(BookApi.class, Constant.API_BASE_URL)
                        .getBookDetail(collBook.get_id()));
            }
        }
        //zip可能不是一个好方法。
        Single.zip(observables, new Function<Object[], List<CollBookBean>>() {
            @Override
            public List<CollBookBean> apply(Object[] objects) throws Exception {
                List<CollBookBean> newCollBooks = new ArrayList<CollBookBean>(objects.length);
                for (int i = 0; i < collBooks.size(); ++i) {
                    CollBookBean oldCollBook = collBooks.get(i);
                    CollBookBean newCollBook = ((BookDetailBean) objects[i]).getCollBookBean();
                    //如果是oldBook是update状态，或者newCollBook与oldBook章节数不同
                    if (oldCollBook.isUpdate() ||
                            !oldCollBook.getLastChapter().equals(newCollBook.getLastChapter())) {
                        newCollBook.setUpdate(true);
                    } else {
                        newCollBook.setUpdate(false);
                    }
                    newCollBook.setLastRead(oldCollBook.getLastRead());
                    newCollBooks.add(newCollBook);
                    //存储到数据库中
//                    BookRepository.getInstance()
//                            .saveCollBooks(newCollBooks);
                }
                return newCollBooks;
            }
        })
                .compose(RxUtils::toSimpleSingle)
                .subscribe(new SingleObserver<List<CollBookBean>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        addDisposable(d);
                    }

                    @Override
                    public void onSuccess(List<CollBookBean> value) {
                        //跟原先比较
                        mView.finishUpdate();
                        mView.complete();
                    }

                    @Override
                    public void onError(Throwable e) {
                        //提示没有网络
                        mView.showErrorTip(e.toString());
                        mView.complete();
                        DLog.e(e);
                    }
                });
    }

    //更新每个CollBook的目录
    private void updateCategory(List<CollBookBean> collBookBeans) {
        List<Single<List<BookChapterBean>>> observables = new ArrayList<>(collBookBeans.size());
        for (CollBookBean beaned : collBookBeans) {
            observables.add(
                    RxjavaRetrofitRequestUtil.getInstance().getWithHost(BookApi.class, Constant.API_BASE_URL).getBookChapterPackage(beaned.get_id(), "chapter")
                            .map(bean -> {
                                if (bean.getMixToc() == null) {
                                    return new ArrayList<BookChapterBean>(1);
                                } else {
                                    return bean.getMixToc().getChapters();
                                }
                            })
            );
        }
        Iterator<CollBookBean> it = collBookBeans.iterator();
        //执行在上一个方法中的子线程中
        Single.concat(observables)
                .subscribe(
                        chapterList -> {

                            for (BookChapterBean bean : chapterList) {
                                bean.setId(MD5Utils.strToMd5By16(bean.getLink()));
                            }

                            CollBookBean bean = it.next();
                            bean.setLastRead(StringUtils.
                                    dateConvert(System.currentTimeMillis(), Constant.FORMAT_BOOK_DATE));
                            bean.setBookChapters(chapterList);
                        }
                );
    }
}
